#ifndef NETWORK_H
#define NETWORK_H

#define MAXLEN 1024
#include "SDL/SDL.h"
#include "SDL/SDL_net.h"
#include "SDL/SDL_thread.h"

#include <vector>
#include <queue>
#include <iostream>
#include <sstream>

/*special characters to send data:
"/" start of message , end of message and command delimiter
"#" field delimiter
*/
 enum NetCommand
	{ //Enumerates server/client commands

    //Setup / control commands
       CREATE_NEW_ACCOUNT =1,
       LOGIN_WITH_ACCOUNT = 2,
       ACCOUNT_ACCEPTED =3,
       DUPLICATE_ACCOUNT = 4,
       UNKNOW_USERNAME = 5,
       BAD_PASSWORD = 6,
       NEW_ACCOUNT_ACCEPTED = 7,


	//Movement commands
	   SEND_UP = 101,//Key UP USE: SEND_UP
	   SEND_DOWN = 102,//Key DOWN USE: SEND_DOWN
	   SEND_LEFT = 103,//Key LEFT USE: SEND_LEFT
	   SEND_RIGHT = 104,//Key RIGHT USE: SEND_RIGHT
	   SEND_ENTER = 105,//ENTER key

    //Level Load / Game syncronism

//Data send

        SEND_SKILL = 300,
        SEND_RACE = 301,
        SEND_ITEM = 302,

	   EMPTY_COMMAND =  65535  //An empty command, USE: EMPTY_COMMAND
  	};


using namespace std;

class cNetwork;

class cClient //the connected clients
{
public:
//functions
cClient();//creator
virtual ~cClient();//destructor
void StartThreads();//Start listener thread
static int listener( void *data );//Listener Thread
void Send(const char* Msg);//Send data to client
void SockSend(NetCommand Command,const char* Msg);//Send Data

//variables
cNetwork *_server;//To comunicate with main server instance
TCPsocket socket;//client socket
SDL_Thread *ListenerThread;//The network client thread
int         threadReturnValueclient;
Uint16 UID;//Unique identifier
bool Connected;//socket connected?
bool Login; //loged in?

};

class cNetwork//main network server class
{
      friend class cClient;

    public:
        //functions
        cNetwork();
        virtual ~cNetwork();
        void Start(Uint16 MAXUsers, Uint16 Port);
        void CleanClient(unsigned int Client);//clean a client so we can use it
        static int Master( void *data );//Master listener function/thread
        void ClearClients();//Clear disconnected clients
        void Finish();//close all client connections and finish server

        //variables
        queue<std::string> InputQueue;//Here we store received data
        queue<std::string> LoginQueue;//Here we store login requests
        SDL_sem *ClientsLock; //Semaphore to prevent server from accesing a variable from different threads
        cNetwork *myserver;//server pointer
        vector<cClient*> Clients;//Here I store clients
        SDL_Thread *MasterThread;//The Master thread >> accepts new clients
        int         threadReturnMaster;//return value for master thread
        bool ShutDown;//closing the server?

    private:
        //private variables
        IPaddress ip;//Server ip address
        TCPsocket ServerSock; //Server socket
};

#endif // NETWORK_H
